package com.zmn.oms.third.jddj.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.ltsopensource.core.domain.Job;
import com.zmn.base.common.data.common.dro.area.AreaDRO;
import com.zmn.base.common.data.dubbo.interfaces.area.AreaListRemoteService;
import com.zmn.cds.httpcall.CdsHttpCallClient;
import com.zmn.cds.httpcall.CdsHttpCallResult;
import com.zmn.cds.httpcall.biz.custom_invocation.CustomInvocationDIO;
import com.zmn.cds.httpcall.biz.orderclue.QueryOrderClueDRO;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.consts.GlobalDict;
import com.zmn.manager.lts.interfaces.task.TaskManager;
import com.zmn.manager.redis.RedisManager;
import com.zmn.oms.business.interfaces.baidumap.BaiduMapBService;
import com.zmn.oms.common.constant.CdsConsts;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderLogConsts;
import com.zmn.oms.common.constant.RedisKeyConsts;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.manager.utils.TaskConsts;
import com.zmn.oms.model.bo.order.OrderBO;
import com.zmn.oms.model.dto.baidumap.LngLatLocation;
import com.zmn.oms.model.dto.order.proxy.CancelOrderDTO;
import com.zmn.oms.model.dto.order.proxy.CreateOrderDTO;
import com.zmn.oms.model.dto.order.proxy.OrderDiscountDTO;
import com.zmn.oms.model.dto.order.proxy.OrderLogDTO;
import com.zmn.oms.model.dto.product.OrderProductDTO;
import com.zmn.oms.model.entity.order.OrderExtend;
import com.zmn.oms.model.entity.remark.OrderRemark;
import com.zmn.oms.model.entity.remark.OrderRemarkDetail;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.entity.work.OrderWorkLogChange;
import com.zmn.oms.model.vo.work.ZsOrderWorkVO;
import com.zmn.oms.services.interfaces.order.OrderExtendService;
import com.zmn.oms.services.interfaces.remark.OrderRemarkDetailService;
import com.zmn.oms.services.interfaces.remark.OrderRemarkService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.third.jddj.JddjConsts;
import com.zmn.oms.third.jddj.JddjUtil;
import com.zmn.oms.third.jddj.api.*;
import com.zmn.oms.third.jddj.dto.JddjExtOuterDataDTO;
import com.zmn.oms.third.jddj.dto.JddjRequestDTO;
import com.zmn.oms.third.jddj.dto.JddjResponseDTO;
import com.zmn.oms.third.jddj.dto.JddjResultDTO;
import com.zmn.oms.third.jddj.service.JddjService;
import com.zmn.oms.zmn.business.interfaces.proxy.ProxyOrderBService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkQueryBService;
import com.zmn.oms.zmn.business.interfaces.work.autoflow.WorkFlowContextBService;
import com.zmn.pay.common.constant.PayConsts;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.net.URLDecoder;
import java.util.*;
import java.util.regex.Pattern;

/**
 * 京东到家渠道对接接口实现
 *
 * @author xiewenbing
 * @date 2021/01/18
 */
@Slf4j
@Service
public class JddjServiceImpl implements JddjService {

    @Autowired
    private ZsOrderWorkQueryBService zsOrderWorkQueryBService;

    @Autowired
    private ProxyOrderBService proxyOrderBService;

    @Autowired
    private OrderRemarkService orderRemarkService;

    @Autowired
    private WorkFlowContextBService workFlowContextBService;

    @Autowired
    private OrderRemarkDetailService orderRemarkDetailService;

    @Autowired
    private OrderWorkService orderWorkService;
    @Autowired
    private OrderExtendService orderExtendService;

    @Resource
    private RedisManager redisManager;

    @Resource
    TaskManager taskManager;

    @Autowired
    private BaiduMapBService baiduMapBService;

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    protected AreaListRemoteService areaListRemoteService;

    /**
     * 处理创建订单请求
     *
     * @param requestDTO
     * @throws OmsBaseException
     */
    @Override
    public void handleCreateOrder(JddjRequestDTO requestDTO) throws OmsBaseException {
        // 请求参数验证
        this.verifyRequestDTO(requestDTO);

        // 解析数据
        JddjCreateOrderData createOrderData;
        try {
            createOrderData = JSON.parseObject(requestDTO.getJd_param_json(), JddjCreateOrderData.class);
        } catch (Exception exception) {
            throw new OmsBaseException("解析数据失败");
        }

        if (Objects.isNull(createOrderData)) {
            throw new OmsBaseException("解析数据失败");
        }

        // 处理请求
        log.info("【{}】创建订单，【{}】", JddjConsts.CHANNEL_NAME, createOrderData.getBillId());

        // 订单去重
        ZsOrderWorkVO zsOrderWorkVO = zsOrderWorkQueryBService.findOrderWorkByOuterId(createOrderData.getBillId(), OrderConsts.CHANNEL_ID_JD_DAOJIA);
        if (Objects.nonNull(zsOrderWorkVO)) {
            throw new OmsBaseException("订单已经存在");
        }

        // 渠道订单id格式判断是否位数字
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        if (!pattern.matcher(createOrderData.getBillId()).matches()) {
            throw new OmsBaseException("渠道订单id格式不正确");
        }

        // 添加到定时任务中
        this.addCreateOrderJob(createOrderData.getBillId());
    }

    /**
     * 处理取消订单请求
     *
     * @param requestDTO
     * @throws OmsBaseException
     */
    @Override
    public void handleCancelOrder(JddjRequestDTO requestDTO) throws OmsBaseException {

        // 请求参数验证
        this.verifyRequestDTO(requestDTO);

        // 解析数据
        JddjCancelOrderData cancelOrderData;
        try {
            cancelOrderData = JSON.parseObject(requestDTO.getJd_param_json(), JddjCancelOrderData.class);
        } catch (Exception exception) {
            throw new OmsBaseException("解析数据失败");
        }

        if (Objects.isNull(cancelOrderData)) {
            throw new OmsBaseException("解析数据失败");
        }

        if (!Objects.equals(cancelOrderData.getStatusId(), JddjConsts.AGREE_CANCEL_APPLY)) {
            log.info("【{}】取消订单不处理 - 商家拒绝申请，【{}】", JddjConsts.CHANNEL_NAME, cancelOrderData.getBillId());
            return;
        }

        // 处理请求
        log.info("【{}】取消订单，【{}】", JddjConsts.CHANNEL_NAME, cancelOrderData.getBillId());

        ZsOrderWorkVO zsOrderWorkVO = zsOrderWorkQueryBService.findOrderWorkByOuterId(cancelOrderData.getBillId(), OrderConsts.CHANNEL_ID_JD_DAOJIA);
        if (Objects.isNull(zsOrderWorkVO)) {
            throw new OmsBaseException("查找不到对应的订单");
        }

        // 取消订单数据构建
        CancelOrderDTO cancelDTO = new CancelOrderDTO();
        cancelDTO.setOrderId(zsOrderWorkVO.getOrderId());
        cancelDTO.setOuterId(zsOrderWorkVO.getOuterId());
        cancelDTO.setChannelId(OrderConsts.CHANNEL_ID_JD_DAOJIA);
        cancelDTO.setOperatorId(Long.valueOf(OrderConsts.CHANNEL_ID_JD_DAOJIA));
        cancelDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_CHANNEL);
        cancelDTO.setRemark(Optional.ofNullable(cancelOrderData.getRemark()).orElse("用户取消"));

        // 取消订单
        try {
            proxyOrderBService.cancelOrder(cancelDTO);
        } catch (OmsBaseException omsBaseException) {

            log.error("【{}】取消订单失败 消息:[{}]", JddjConsts.CHANNEL_NAME, omsBaseException.getMessage());
            throw new OmsBaseException(Optional.ofNullable(omsBaseException.getMessage()).orElse("处理失败"));
        }
    }

    /**
     * 刷新token
     *
     * @param tokenContent
     * @throws OmsBaseException
     */
    @Override
    public void handleRefreshToken(String tokenContent) throws OmsBaseException {

        // 参数判断
        if (StringUtil.isBlank(tokenContent)) {
            throw new OmsBaseException("数据为空");
        }

        // 解析数据
        JddjTokenData tokenData;
        try {
            tokenData = JSON.parseObject(tokenContent, JddjTokenData.class);
        } catch (Exception exception) {
            throw new OmsBaseException("token数据错误");
        }

        if (Objects.isNull(tokenData)) {
            throw new OmsBaseException("token数据错误");
        }

        // 计算有效时间
        Integer expiresInTime = (12 * 30 * 24 * 3600);
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        if (StringUtil.isNotBlank(tokenData.getTime()) && pattern.matcher(tokenData.getExpiresIn()).matches()) {
            Long ext = Long.valueOf(tokenData.getExpiresIn());
            if (ext > 0) {
                expiresInTime = ext.intValue();
            }
        }

        // 保存到redis
        redisManager.setex(RedisKeyConsts.JDDJ_TOKEN_REDIS_KEY, tokenContent, expiresInTime);
    }

    /**
     * 请求参数验证
     *
     * @param requestDTO
     * @throws OmsBaseException
     */
    protected void verifyRequestDTO(JddjRequestDTO requestDTO) throws OmsBaseException {

        if (!JddjConsts.POWER_ON) {
            throw new OmsBaseException("接口暂不支持");
        }

        // 参数判断
        if (Objects.isNull(requestDTO) || StringUtil.isBlank(requestDTO.getJd_param_json())) {
            throw new OmsBaseException("请求参数为空");
        }

        try {
            String timestamp = requestDTO.getTimestamp();
            String paramJson = requestDTO.getJd_param_json();
            requestDTO.setTimestamp(URLDecoder.decode(timestamp, "utf-8"));
            requestDTO.setJd_param_json(URLDecoder.decode(paramJson, "utf-8"));
        } catch (Exception e) {
            throw new OmsBaseException("请求参数 URLDecode 失败");
        }

        // 签名验证
        if (!JddjUtil.verifySign(requestDTO)) {
            throw new OmsBaseException("数据签名验证失败");
        }
    }

    /**
     * 同步订单确认
     *
     * @param orderWorkLogChange
     * @throws OmsBaseException
     */
    @Override
    public void syncOrderConfirm(OrderWorkLogChange orderWorkLogChange) throws OmsBaseException {

        // 参数验证
        if (Objects.isNull(orderWorkLogChange)) {
            throw new OmsBaseException("参数为null");
        }

        // 渠道订单id
        String outerId = orderWorkLogChange.getOuterId();
        if (StringUtil.isBlank(outerId)) {
            throw new OmsBaseException("渠道订单ID为空");
        }

        /*** 1. 同步订单打印 ***/
        // 订单打印接口数据
        JddjSyncOrderConfirmData syncOrderConfirmData = new JddjSyncOrderConfirmData();
        syncOrderConfirmData.setOrderId(Long.valueOf(outerId));

        // 生成请求参数
        JddjRequestDTO requestDTO = this.makeRequestDTO(JSON.toJSONString(syncOrderConfirmData));

        // 发送请求
        String response = JddjUtil.postRequest(JddjConsts.PATH_CONFIRM, requestDTO);
        if (StringUtil.isBlank(response)) {
            throw new OmsBaseException("发送订单打印(订单确认)请求失败");
        }

        log.info("【{}】发送订单打印(订单确认)请求，【{}】【{}】", JddjConsts.CHANNEL_NAME, outerId, response);
        // 解析应答
        this.parseSyncResponse(response);

        /*** 2. 同步拣货完成且顾客自提 ***/
        // 拣货完成且顾客自提数据
        JddjSyncOrderSelfMentionData syncOrderSelfMentionData = new JddjSyncOrderSelfMentionData();
        syncOrderSelfMentionData.setOrderId(outerId);
        syncOrderSelfMentionData.setOperator(orderWorkLogChange.getOperatorName());

        // 生成请求参数
        requestDTO = this.makeRequestDTO(JSON.toJSONString(syncOrderSelfMentionData));

        // 发送请求
        response = JddjUtil.postRequest(JddjConsts.PATH_ORDER_SELF_MENTION, requestDTO);
        if (StringUtil.isBlank(response)) {
            throw new OmsBaseException("发送拣货完成且顾客自提请求失败");
        }

        log.info("【{}】发送拣货完成且顾客自提请求，【{}】【{}】", JddjConsts.CHANNEL_NAME, outerId, response);
        // 解析应答
        this.parseSyncResponse(response);
    }

    /**
     * 同步师傅上门
     *
     * @param orderWorkLogChange
     * @throws OmsBaseException
     */
    @Override
    public void syncMasterVisit(OrderWorkLogChange orderWorkLogChange) throws OmsBaseException {

        // 参数验证
        if (Objects.isNull(orderWorkLogChange)) {
            throw new OmsBaseException("参数为null");
        }

        // 渠道订单id
        String outerId = orderWorkLogChange.getOuterId();
        if (StringUtil.isBlank(outerId)) {
            throw new OmsBaseException("渠道订单ID为空");
        }

        // 拣货完成且商家自送接口数据(同步师傅上门)
        JddjSyncMasterVisitData syncMasterVisitData = new JddjSyncMasterVisitData();
        syncMasterVisitData.setOrderId(outerId);
        syncMasterVisitData.setOperator(orderWorkLogChange.getOperatorName());

        // 生成请求参数
        JddjRequestDTO requestDTO = this.makeRequestDTO(JSON.toJSONString(syncMasterVisitData));

        // 发送请求
        String response = JddjUtil.postRequest(JddjConsts.PATH_VISIT, requestDTO);
        if (StringUtil.isBlank(response)) {
            throw new OmsBaseException("发送拣货完成且商家自送(师傅上门)请求失败");
        }

        log.info("【{}】发送拣货完成且商家自送(师傅上门)请求，【{}】【{}】", JddjConsts.CHANNEL_NAME, outerId, response);
        // 解析应答
        this.parseSyncResponse(response);
    }

    /**
     * 同步订单完成
     *
     * @param orderWorkLogChange
     * @throws OmsBaseException
     */
    @Override
    public void syncOrderComplete(OrderWorkLogChange orderWorkLogChange) throws OmsBaseException {

        // 参数验证
        if (Objects.isNull(orderWorkLogChange)) {
            throw new OmsBaseException("参数为null");
        }

        // 渠道订单id
        String outerId = orderWorkLogChange.getOuterId();
        if (StringUtil.isBlank(outerId)) {
            throw new OmsBaseException("渠道订单ID为空");
        }

        // 删除订单核销码redis
        String redisKey = String.format(RedisKeyConsts.JDDJ_VCODE_REDIS_KEY, orderWorkLogChange.getOrderId());
        redisManager.del(redisKey);

        // 订单妥投接口数据(同步订单完成)
        JddjSyncOrderCompleteData syncOrderCompleteData = new JddjSyncOrderCompleteData();
        syncOrderCompleteData.setOrderId(Long.valueOf(outerId));
        syncOrderCompleteData.setOperTime(DateUtil.toString(Optional.ofNullable(orderWorkLogChange.getOpTime()).orElse(DateUtil.getNow())));
        syncOrderCompleteData.setOperPin(orderWorkLogChange.getOperatorName());

        // 生成请求参数
        JddjRequestDTO requestDTO = this.makeRequestDTO(JSON.toJSONString(syncOrderCompleteData));

        // 发送请求
        String response = JddjUtil.postRequest(JddjConsts.PATH_COMPLETE, requestDTO);
        if (StringUtil.isBlank(response)) {
            throw new OmsBaseException("订单妥投(订单完成)请求失败");
        }

        log.info("【{}】订单妥投(订单完成)请求，【{}】【{}】", JddjConsts.CHANNEL_NAME, outerId, response);
        // 解析应答
        this.parseSyncResponse(response);
    }

    /**
     * 同步订单取消
     *
     * @param orderWorkLogChange
     * @throws OmsBaseException
     */
    @Override
    public void syncOrderCancel(OrderWorkLogChange orderWorkLogChange) throws OmsBaseException {

        // 参数验证
        if (Objects.isNull(orderWorkLogChange)) {
            throw new OmsBaseException("参数为null");
        }

        // 渠道订单id
        String outerId = orderWorkLogChange.getOuterId();
        if (StringUtil.isBlank(outerId)) {
            throw new OmsBaseException("渠道订单ID为空");
        }

        // 删除订单核销码redis
        String redisKey = String.format(RedisKeyConsts.JDDJ_VCODE_REDIS_KEY, orderWorkLogChange.getOrderId());
        redisManager.del(redisKey);

        // 判断是否为渠道取消的订单，是则不处理
        if ((Objects.equals(orderWorkLogChange.getOperatorId(), Long.valueOf(OrderConsts.CHANNEL_ID_JD_DAOJIA))) &&
                (orderWorkLogChange.getOperatorType() == GlobalConsts.OPERATE_USER_TYPE_CHANNEL)) {
            throw new OmsBaseException("工单为渠道方取消，无需同步");
        }

        // 获取取消原因
        String cancelReason = getOrderCancelReason(orderWorkLogChange.getOrderId(), orderWorkLogChange.getWorkId());

        // 订单取消接口数据(同步订单取消)
        JddjSyncOrderCancelData syncOrderCancelData = new JddjSyncOrderCancelData();
        syncOrderCancelData.setOrderId(Long.valueOf(outerId));
        syncOrderCancelData.setOperTime(DateUtil.toString(Optional.ofNullable(orderWorkLogChange.getOpTime()).orElse(DateUtil.getNow())));

        syncOrderCancelData.setOperPin(orderWorkLogChange.getOperatorName());
        syncOrderCancelData.setOperRemark(cancelReason);

        // 生成请求参数
        JddjRequestDTO requestDTO = this.makeRequestDTO(JSON.toJSONString(syncOrderCancelData));

        // 发送请求
        String response = JddjUtil.postRequest(JddjConsts.PATH_CANCEL, requestDTO);
        if (StringUtil.isBlank(response)) {
            throw new OmsBaseException("订单取消请求失败");
        }

        log.info("【{}】订单取消请求，【{}】【{}】", JddjConsts.CHANNEL_NAME, outerId, response);
        // 解析应答
        this.parseSyncResponse(response);
    }

    /**
     * 创建订单
     *
     * @param outerId
     * @throws OmsBaseException
     */
    @Override
    public void createOrderByChannelOrderId(String outerId) throws OmsBaseException {

        // 参数判断
        if (StringUtil.isBlank(outerId)) {
            throw new OmsBaseException("渠道订单id为空");
        }

        // 订单去重
        ZsOrderWorkVO zsOrderWorkVO = zsOrderWorkQueryBService.findOrderWorkByOuterId(outerId, OrderConsts.CHANNEL_ID_JD_DAOJIA);
        if (Objects.nonNull(zsOrderWorkVO)) {
            throw new OmsBaseException("订单已经存在");
        }

        // 查询订单信息
        JddjQuerySimpleOrderData querySimpleOrderData = new JddjQuerySimpleOrderData();
        querySimpleOrderData.setOrderId(Long.valueOf(outerId));
        querySimpleOrderData.setPageNo(1L);
        querySimpleOrderData.setPageSize(20);
        querySimpleOrderData.setReturnedFields(JddjConsts.QUERY_RETURN_FIELDS);

        // 生成请求参数
        JddjRequestDTO requestDTO = this.makeRequestDTO(JSON.toJSONString(querySimpleOrderData));

        // 发送请求
        String response = JddjUtil.postRequest(JddjConsts.PATH_QUERY, requestDTO);
        if (StringUtil.isBlank(response)) {
            throw new OmsBaseException("订单查询请求失败");
        }

        log.info("【{}】订单查询请求，【{}】【{}】", JddjConsts.CHANNEL_NAME, outerId, response);

        // 解析应答
        List<JddjOrderData> orderDataList = this.parseOrderQueryResponse(response);
        if (CollectionUtils.isEmpty(orderDataList)) {
            throw new OmsBaseException("订单查询结果为空");
        }

        // 生成创建订单的数据
        CreateOrderDTO createOrderDTO = buildCreateOrderDTO(orderDataList.get(0));

        // 创建订单
        OrderWork orderWork;
        try {
            OrderBO orderBO = proxyOrderBService.createOrder(createOrderDTO);
            orderWork = orderBO.getOrderWork();

        } catch (OmsBaseException omsBaseException) {

            log.info("【{}】保存订单异常，参数【{}】 OmsBaseException【{}】 ", JddjConsts.CHANNEL_NAME, createOrderDTO.toString(), omsBaseException.getMessage());
            throw omsBaseException;
        } catch (Exception exception) {

            log.info("【{}】保存订单失败，参数【{}】 Exception【{}】 ", JddjConsts.CHANNEL_NAME, createOrderDTO.toString(), exception.getMessage());
            throw new OmsBaseException("创建订单失败");
        }

        log.info("【{}】保存订单成功 OrderId:[{}]", JddjConsts.CHANNEL_NAME, orderWork.getOrderId());

        // 工单自动流转
        workFlowContextBService.asyncAutoFlow(orderWork.getOrderId(), orderWork.getWorkId());
    }

    /**
     * 创建订单
     *
     * @param msg
     * @throws OmsBaseException
     */
    @Override
    public Long createOrderByMsgContent(String msg) throws OmsBaseException {
        // 解析应答
        List<JddjOrderData> orderDataList = this.parseOrderQueryResponse(msg);
        if (CollectionUtils.isEmpty(orderDataList)) {
            throw new OmsBaseException("订单查询结果为空");
        }

        // 生成创建订单的数据
        CreateOrderDTO createOrderDTO = buildCreateOrderDTO(orderDataList.get(0));

        // 创建订单
        OrderWork orderWork;
        try {
            OrderBO orderBO = proxyOrderBService.createOrder(createOrderDTO);
            orderWork = orderBO.getOrderWork();

        } catch (OmsBaseException omsBaseException) {

            log.info("【{}】保存订单异常，参数【{}】 OmsBaseException【{}】 ", JddjConsts.CHANNEL_NAME, createOrderDTO.toString(), omsBaseException.getMessage());
            throw omsBaseException;
        } catch (Exception exception) {

            log.info("【{}】保存订单失败，参数【{}】 Exception【{}】 ", JddjConsts.CHANNEL_NAME, createOrderDTO.toString(), exception.getMessage());
            throw new OmsBaseException("创建订单失败");
        }

        log.info("【{}】保存订单成功 OrderId:[{}]", JddjConsts.CHANNEL_NAME, orderWork.getOrderId());

        // 工单自动流转
        workFlowContextBService.asyncAutoFlow(orderWork.getOrderId(), orderWork.getWorkId());

        return orderWork.getWorkId();
    }

    /**
     * 效验核销码
     *
     * @param orderId
     * @param vCode
     */
    @Override
    public void validateVerificationCode(Long orderId, String vCode) throws OmsBaseException {

//        if (NumberUtil.isNullOrZero(orderId) || StringUtil.isBlank(vCode)) {
//            throw new OmsBaseException("参数不能为空");
//        }
//
//        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);
//        if (Objects.isNull(orderWork)) {
//            throw new OmsBaseException("订单不存在");
//        }
//
//        if (!Objects.equals(orderWork.getInputType(), OrderConsts.ORDER_INPUT_TYPE_API)) {
//            log.info("【{}】订单录入方式不为API接入，不需要核销码验证", JddjConsts.CHANNEL_NAME);
//            return;
//        }
//
//        if (!Objects.equals(orderWork.getChannelId(), OrderConsts.CHANNEL_ID_JD_DAOJIA)) {
//            log.info("【{}】订单来源渠道非京东到家，不需要核销码验证", JddjConsts.CHANNEL_NAME);
//            return;
//        }
//
//        // 版本上线前的订单无需核销码校验
//        if (orderWork.getReceiveTime().getTime() < DateUtil.parse("2021-04-02 00:00:00").getTime()) {
//            log.info("【{}】订单录入时间为版本更新前，不需要核销码验证", JddjConsts.CHANNEL_NAME);
//            return;
//        }
//
//        /**  需求发生变化
//         // 订单下单时间超过36小时，无需校验核销码
//         if (orderWork.getReceiveTime().getTime() < DateUtil.getNowDeferHours(36).getTime()) {
//         log.info("【{}】订单录入时间在下单时间36小时之后，不需要核销码验证", JddjConsts.CHANNEL_NAME);
//         return;
//         }
//         */
//
//        String redisKey = String.format(RedisKeyConsts.JDDJ_VCODE_REDIS_KEY, orderId);
//        if (StringUtil.isNotBlank(redisManager.get(redisKey))) {
//            throw new OmsBaseException("已校验核销码，无需要再次进行");
//        }
//
//        // 渠道订单id
//        String outerId = orderWork.getOuterId();
//        if (StringUtil.isBlank(outerId)) {
//            throw new OmsBaseException("渠道订单ID为空");
//        }
//
//        // 订单自提码核验接口数据
//        JddjSyncVerficationCodeData syncVerficationCodeData = new JddjSyncVerficationCodeData();
//        syncVerficationCodeData.setOrderId(outerId);
//        syncVerficationCodeData.setSelfPickCode(vCode);
//        syncVerficationCodeData.setOperPin("啄木鸟");
//
//        // 生成请求参数
//        JddjRequestDTO requestDTO = this.makeRequestDTO(JSON.toJSONString(syncVerficationCodeData));
//
//        // 发送请求
//        String response = JddjUtil.postRequest(JddjConsts.PATH_VERFICATION_CODE, requestDTO);
//        if (StringUtil.isBlank(response)) {
//            throw new OmsBaseException("订单自提码核验请求失败");
//        }
//
//        log.info("【{}】订单自提码核验请求，【{}】【{}】", JddjConsts.CHANNEL_NAME, outerId, response);
//        // 解析应答
//        this.parseSyncResponse(response);
//
//        // 保存到redis
//        int timeout = 3600 * 34 * 30;    // 有效时间为一个月
//        redisManager.setex(redisKey, vCode, timeout);
//
//        // 添加日志
//        OrderLogDTO orderLogDTO = new OrderLogDTO();
//        orderLogDTO.setOrderId(orderWork.getOrderId());
//        orderLogDTO.setOuterId(outerId);
//        orderLogDTO.setChannelId(OrderConsts.CHANNEL_ID_JD_DAOJIA);
//        orderLogDTO.setOperatorId((long) OrderConsts.CHANNEL_ID_JD_DAOJIA);
//        orderLogDTO.setOperatorType(com.zmn.common.constant.GlobalConsts.OPERATE_USER_TYPE_CHANNEL);
//        orderLogDTO.setType(OrderLogConsts.ORDER_LOG_TYPE_CHANNEL_REMARK);
//        orderLogDTO.setOperatorLogRemark(String.format("核销码校验，核销码:%s", vCode));
//        proxyOrderBService.addOrderLog(orderLogDTO);

        if (NumberUtil.isNullOrZero(orderId) || StringUtil.isBlank(vCode)) {
            throw new OmsBaseException("参数不能为空");
        }

        log.info("接口<orderWorkService.findOrderWorkByKey>的入参orderId:{}", orderId);
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);
        log.info("接口<orderWorkService.findOrderWorkByKey>的响应:{}", JSONObject.toJSONString(orderWork));
        if (Objects.isNull(orderWork)) {
            throw new OmsBaseException("订单不存在");
        }

        Integer channelId = orderWork.getChannelId();
        String channelName = "";
        if (channelId.equals(OrderConsts.CHANNEL_ID_JD_DAOJIA)) {
            channelName = JddjConsts.CHANNEL_NAME;
        }

        if (channelId.equals(OrderConsts.CHANNEL_ID_JD_QTDJ)) {
            channelName = JddjConsts.CHANNEL_NAME_QTDJ;
        }

        if (!Objects.equals(orderWork.getInputType(), OrderConsts.ORDER_INPUT_TYPE_API)) {
            log.info("【{}】订单录入方式不为API接入，不需要核销码验证", channelName);
            return;
        }

        if (!Objects.equals(orderWork.getChannelId(), OrderConsts.CHANNEL_ID_JD_DAOJIA) &&
                !Objects.equals(orderWork.getChannelId(), OrderConsts.CHANNEL_ID_JD_QTDJ)) {
            log.info("【{}】订单来源渠道非京东到家，不需要核销码验证", channelName);
            return;
        }

        // 版本上线前的订单无需核销码校验
        if (orderWork.getReceiveTime().getTime() < DateUtil.parse("2021-04-02 00:00:00").getTime()) {
            log.info("【{}】订单录入时间为版本更新前，不需要核销码验证", channelName);
            return;
        }


        String redisKey = String.format(RedisKeyConsts.JDDJ_VCODE_REDIS_KEY, orderId);
        if (StringUtil.isNotBlank(redisManager.get(redisKey))) {
            throw new OmsBaseException("已校验核销码，无需要再次进行");
        }

        // 渠道订单id
        String outerId = orderWork.getOuterId();
        if (StringUtil.isBlank(outerId)) {
            throw new OmsBaseException("渠道订单ID为空");
        }

        // 新的青提到家店铺，调用CDS
        // 创建 CdsHttpCallClient 对象
        CdsHttpCallClient client = CdsHttpCallClient.newInstance(
                CdsConsts.HttpCall.BASE_URL,
                CdsConsts.HttpCall.MODEL_NAME,
                CdsConsts.HttpCall.SECRET_KEY
        );

        CustomInvocationDIO customInvocationDIO = new CustomInvocationDIO();
        customInvocationDIO.setZmnOrderId(orderId);
        customInvocationDIO.setCustomFun("verify_code");
        customInvocationDIO.setFunName("校验核销码");
        customInvocationDIO.setData(vCode);

        log.info("client.customInvocation的参数:{}", JSONObject.toJSONString(customInvocationDIO));
        CdsHttpCallResult customInvocationResult = client.customInvocation(customInvocationDIO);
        log.info("client.customInvocation的响应:{}", JSONObject.toJSONString(customInvocationResult));
        if (customInvocationResult.isStatusBool()) {

            // 保存到redis
            int timeout = 3600 * 34 * 30;    // 有效时间为一个月
            redisManager.setex(redisKey, vCode, timeout);

            // 添加日志
            OrderLogDTO orderLogDTO = new OrderLogDTO();
            orderLogDTO.setOrderId(orderWork.getOrderId());
            orderLogDTO.setOuterId(outerId);
            orderLogDTO.setChannelId(OrderConsts.CHANNEL_ID_JD_DAOJIA);
            orderLogDTO.setOperatorId((long) OrderConsts.CHANNEL_ID_JD_DAOJIA);
            orderLogDTO.setOperatorType(com.zmn.common.constant.GlobalConsts.OPERATE_USER_TYPE_CHANNEL);
            orderLogDTO.setType(OrderLogConsts.ORDER_LOG_TYPE_CHANNEL_REMARK);
            orderLogDTO.setOperatorLogRemark(String.format("核销码校验，核销码:%s", vCode));
            proxyOrderBService.addOrderLog(orderLogDTO);
        } else {
            throw new OmsBaseException(customInvocationResult.getMessage());
        }
    }

    @Override
    public void validateVerificationCodeV2(Long orderId, String vCode) throws OmsBaseException {
        if (NumberUtil.isNullOrZero(orderId) || StringUtil.isBlank(vCode)) {
            throw new OmsBaseException("参数不能为空");
        }

        log.info("接口<orderWorkService.findOrderWorkByKey>的入参orderId:{}", orderId);
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);
        log.info("接口<orderWorkService.findOrderWorkByKey>的响应:{}", JSONObject.toJSONString(orderWork));
        if (Objects.isNull(orderWork)) {
            throw new OmsBaseException("订单不存在");
        }

        Integer channelId = orderWork.getChannelId();
        String channelName = "";
        if (channelId.equals(OrderConsts.CHANNEL_ID_JD_DAOJIA)) {
            channelName = JddjConsts.CHANNEL_NAME;
        }

        if (channelId.equals(OrderConsts.CHANNEL_ID_JD_QTDJ)) {
            channelName = JddjConsts.CHANNEL_NAME_QTDJ;
        }

        if (!Objects.equals(orderWork.getInputType(), OrderConsts.ORDER_INPUT_TYPE_API)) {
            log.info("【{}】订单录入方式不为API接入，不需要核销码验证", channelName);
            return;
        }

        if (!Objects.equals(orderWork.getChannelId(), OrderConsts.CHANNEL_ID_JD_DAOJIA) &&
                !Objects.equals(orderWork.getChannelId(), OrderConsts.CHANNEL_ID_JD_QTDJ)) {
            log.info("【{}】订单来源渠道非京东到家，不需要核销码验证", channelName);
            return;
        }

        // 版本上线前的订单无需核销码校验
        if (orderWork.getReceiveTime().getTime() < DateUtil.parse("2021-04-02 00:00:00").getTime()) {
            log.info("【{}】订单录入时间为版本更新前，不需要核销码验证", channelName);
            return;
        }


        String redisKey = String.format(RedisKeyConsts.JDDJ_VCODE_REDIS_KEY, orderId);
        if (StringUtil.isNotBlank(redisManager.get(redisKey))) {
            throw new OmsBaseException("已校验核销码，无需要再次进行");
        }

        // 渠道订单id
        String outerId = orderWork.getOuterId();
        if (StringUtil.isBlank(outerId)) {
            throw new OmsBaseException("渠道订单ID为空");
        }

        // 新的青提到家店铺，调用CDS
        // 创建 CdsHttpCallClient 对象
        CdsHttpCallClient client = CdsHttpCallClient.newInstance(
                CdsConsts.HttpCall.BASE_URL,
                CdsConsts.HttpCall.MODEL_NAME,
                CdsConsts.HttpCall.SECRET_KEY
        );

        CustomInvocationDIO customInvocationDIO = new CustomInvocationDIO();
        customInvocationDIO.setZmnOrderId(orderId);
        customInvocationDIO.setCustomFun("verify_code");
        customInvocationDIO.setFunName("校验核销码");
        customInvocationDIO.setData(vCode);

        log.info("client.customInvocation的参数:{}", JSONObject.toJSONString(customInvocationDIO));
        CdsHttpCallResult customInvocationResult = client.customInvocation(customInvocationDIO);
        log.info("client.customInvocation的响应:{}", JSONObject.toJSONString(customInvocationResult));
        if (customInvocationResult.isStatusBool()) {

            // 保存到redis
            int timeout = 3600 * 34 * 30;    // 有效时间为一个月
            redisManager.setex(redisKey, vCode, timeout);

            // 添加日志
            OrderLogDTO orderLogDTO = new OrderLogDTO();
            orderLogDTO.setOrderId(orderWork.getOrderId());
            orderLogDTO.setOuterId(outerId);
            orderLogDTO.setChannelId(OrderConsts.CHANNEL_ID_JD_DAOJIA);
            orderLogDTO.setOperatorId((long) OrderConsts.CHANNEL_ID_JD_DAOJIA);
            orderLogDTO.setOperatorType(com.zmn.common.constant.GlobalConsts.OPERATE_USER_TYPE_CHANNEL);
            orderLogDTO.setType(OrderLogConsts.ORDER_LOG_TYPE_CHANNEL_REMARK);
            orderLogDTO.setOperatorLogRemark(String.format("核销码校验，核销码:%s", vCode));
            proxyOrderBService.addOrderLog(orderLogDTO);
        } else {
            throw new OmsBaseException(customInvocationResult.getMessage());
        }
    }

    /**
     * 完成验证
     *
     * @param orderId
     * @param workId
     */
    @Override
    public boolean verifyComplete(Long orderId, Long workId) {

        if (NumberUtil.isNullOrZero(orderId) || NumberUtil.isNullOrZero(workId)) {
            return false;
        }

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        if (Objects.isNull(orderWork)) {
            return false;
        }

        if (!Objects.equals(orderWork.getChannelId(), OrderConsts.CHANNEL_ID_JD_DAOJIA)
                && !Objects.equals(orderWork.getChannelId(), OrderConsts.CHANNEL_ID_JD_QTDJ)) {
            return true;
        }

        // 版本上线前的订单无需核销码校验
        if (orderWork.getReceiveTime().getTime() < DateUtil.parse("2021-04-02 00:00:00").getTime()) {
            return true;
        }

        /**  需求发生变化
         // 订单下单时间超过36小时，无需校验核销码
         if (orderWork.getReceiveTime().getTime() < DateUtil.getNowDeferHours(36).getTime()) {
         return true;
         }
         */

        // 人工录单等订单不进行验证
        if (!Objects.equals(orderWork.getInputType(), OrderConsts.ORDER_INPUT_TYPE_API)) {
            return true;
        }

        OrderExtend orderExtend = orderExtendService.findMiniOrderExtendByOrderId(workId);
        JddjExtOuterDataDTO extOuterDataDTO = JddjExtOuterDataDTO.fromExtOuterDataStr(orderExtend.getExtOuterData());
        if (!extOuterDataDTO.needVerification()) {
            return true; // 无需核销码校验
        }

        String redisKey = String.format(RedisKeyConsts.JDDJ_VCODE_REDIS_KEY, orderId);
        String vCode = redisManager.get(redisKey);

        return StringUtil.isBlank(vCode) ? false : true;
    }

    /**
     * 读取已校验的核销码
     *
     * @param orderId
     * @return
     */
    @Override
    public String getVerificationCode(Long orderId) throws OmsBaseException {

        if (NumberUtil.isNullOrZero(orderId)) {
            throw new OmsBaseException("订单id不能为空");
        }

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);
        if (Objects.isNull(orderWork)) {
            throw new OmsBaseException("没有对应的订单");
        }

        if (!Objects.equals(orderWork.getChannelId(), OrderConsts.CHANNEL_ID_JD_DAOJIA)
                && !Objects.equals(orderWork.getChannelId(), OrderConsts.CHANNEL_ID_JD_QTDJ)) {
            throw new OmsBaseException("订单来源渠道不为京东到家");
        }

        String redisKey = String.format(RedisKeyConsts.JDDJ_VCODE_REDIS_KEY, orderId);
        return redisManager.get(redisKey);
    }

    /**
     * 读取订单取消的原因
     *
     * @param orderId
     * @param workId
     * @return
     */
    protected String getOrderCancelReason(Long orderId, Long workId) {

        // 参数判断
        if (NumberUtil.isNullOrZero(orderId) || NumberUtil.isNullOrZero(workId)) {
            return "";
        }

        // 查询
        String cancelReason = "订单被取消";
        OrderRemark orderRemark = orderRemarkService.findByOrderIdAndType(orderId, workId, OrderConsts.ORDER_REMARK_TYPE_CANCEL);
        if (Objects.isNull(orderRemark)) {
            return cancelReason;
        }

        if (StringUtil.isBlank(orderRemark.getContent())) {

            List<OrderRemarkDetail> remarkDetailList = orderRemarkDetailService.listOrderRemarkDetailByRemarkId(orderId, workId,
                    orderRemark.getRemarkId());
            if (!CollectionUtils.isEmpty(remarkDetailList)) {
                cancelReason = remarkDetailList.get(0).getMapName();
            }
        } else {
            cancelReason = orderRemark.getContent();
        }

        return cancelReason;
    }

    /**
     * 读取redis中的token数据
     *
     * @return
     */
    protected String getToken() {

        String redisContent = redisManager.get(RedisKeyConsts.JDDJ_TOKEN_REDIS_KEY);
        if (StringUtil.isBlank(redisContent)) {
            log.info("【{}】读取token数据失败", JddjConsts.CHANNEL_NAME);
            return "";
        }

        // 解析数据
        JddjTokenData tokenData;
        try {
            tokenData = JSON.parseObject(redisContent, JddjTokenData.class);
        } catch (Exception exception) {
            log.info("【{}】解析token数据异常", JddjConsts.CHANNEL_NAME);
            return "";
        }

        if (Objects.isNull(tokenData)) {
            log.info("【{}】解析token数据失败", JddjConsts.CHANNEL_NAME);
            return "";
        }

        return tokenData.getToken();
    }

    /**
     * 生成请求数据
     *
     * @return
     */
    protected JddjRequestDTO makeRequestDTO(String paramJson) throws OmsBaseException {

        // 读取token
        String token = this.getToken();
        if (StringUtil.isBlank(token)) {
            throw new OmsBaseException("读取token信息失败");
        }

        // 生成请求数据
        JddjRequestDTO requestDTO = new JddjRequestDTO();
        requestDTO.setApp_key(JddjConsts.APP_KEY);
        requestDTO.setFormat(JddjConsts.API_FORMAT);
        requestDTO.setToken(token);
        requestDTO.setV(JddjConsts.API_VERSION);
        requestDTO.setJd_param_json(paramJson);
        requestDTO.setTimestamp(DateUtil.getNowFormatted());
        requestDTO.setSign(JddjUtil.makeSign(requestDTO));

        return requestDTO;
    }

    /**
     * 解析订单同步请求应答
     *
     * @param response
     */
    protected void parseSyncResponse(String response) throws OmsBaseException {

        // 解析数据
        JddjResponseDTO responseDTO;

        try {
            responseDTO = JSON.parseObject(response, JddjResponseDTO.class);
        } catch (Exception exception) {
            throw new OmsBaseException("解析请求应答结果异常");
        }

        if (Objects.isNull(responseDTO)) {
            throw new OmsBaseException("解析请求应答结果失败");
        }

        // 读取错误码
        int code = Integer.valueOf(responseDTO.getCode()).intValue();
        if (code != JddjConsts.RESPONSE_CODE_SUCCESS) {
            throw new OmsBaseException(Optional.ofNullable(responseDTO.getMsg()).orElse(JddjConsts.getErrorMsgByCode(code)));
        }

        if (StringUtil.isBlank(responseDTO.getData())) {
            return;
        }

        try {
            responseDTO = JSON.parseObject(responseDTO.getData(), JddjResponseDTO.class);
        } catch (Exception exception) {
            throw new OmsBaseException("解析请求应答数据异常");
        }

        if (Objects.isNull(responseDTO)) {
            throw new OmsBaseException("解析请求应答数据失败");
        }

        code = Integer.valueOf(responseDTO.getCode()).intValue();
        if (code == JddjConsts.RESPONSE_CODE_SUCCESS) {
            return;
        }

        throw new OmsBaseException(Optional.ofNullable(responseDTO.getMsg()).orElse(JddjConsts.getErrorMsgByCode(code)));
    }

    /**
     * 生成创建订单的数据
     *
     * @param orderData
     * @return
     */
    protected CreateOrderDTO buildCreateOrderDTO(JddjOrderData orderData) throws OmsBaseException {

        // 参数检验
        if (Objects.isNull(orderData)) {
            throw new OmsBaseException("订单数据为空");
        }

        String userPhone = Optional.ofNullable(orderData.getBuyerMobile()).orElse(orderData.getBuyerTelephone());
        if (StringUtil.isBlank(userPhone)) {
            throw new OmsBaseException("联系人电话为空");
        }

        if (!CollectionUtils.isEmpty(orderData.getProduct()) && Objects.equals(orderData.getProduct().get(0).getSkuIdIsv(), "999999")) {
            throw new OmsBaseException("skuId 为 999999，不生成工单");
        }

        // 订单创建数据
        CreateOrderDTO createOrderDTO = new CreateOrderDTO();

        // 输入类型
        createOrderDTO.setInputType(OrderConsts.ORDER_INPUT_TYPE_API);

        // 渠道id
        createOrderDTO.setChannelId(OrderConsts.CHANNEL_ID_JD_DAOJIA);

        // 外部订单id - 母单号
        createOrderDTO.setOuterId(String.valueOf(orderData.getOrderId()));

        // 记录订单的来源系统类型
        JddjExtOuterDataDTO extOuterDataDTO = new JddjExtOuterDataDTO();
        extOuterDataDTO.setSrcOrderType(orderData.getSrcOrderType());
        createOrderDTO.setExtOuterData(extOuterDataDTO.toString());

        // 联系人
        createOrderDTO.setContactName(orderData.getBuyerFullName());

        // 联系人电话
        createOrderDTO.setTelephone(userPhone);

        // 性别
        createOrderDTO.setGender(GlobalDict.GENDER_NO);

        // 预约时间
        Date dutyTime = Objects.nonNull(orderData.getPickDeadline()) ? orderData.getPickDeadline() :
                (Objects.nonNull(orderData.getOrderPreStartDeliveryTime()) ? orderData.getOrderPreStartDeliveryTime() : orderData.getOrderPreEndDeliveryTime());
        if (Objects.nonNull(dutyTime)) {
            createOrderDTO.setDutyTime(dutyTime);
        }

        // 地址
        createOrderDTO.setAddress(orderData.getBuyerFullAddress());

        // 厂商单
        createOrderDTO.setFactory(GlobalConsts.NO);

        // 备注
        createOrderDTO.setRemark(orderData.getOrderBuyerRemark());

        // 业务类型
        createOrderDTO.setBizType(GlobalConsts.BIZ_TYPE_C);

        // 平台
        createOrderDTO.setPlat(GlobalConsts.PLAT_MARK_ZMN);

        // 禁止弃单
        createOrderDTO.setDisableDiscard(GlobalConsts.NO);

        // 操作人
        createOrderDTO.setOperator("系统");

        // 操作人id
        createOrderDTO.setOperatorId((long) GlobalConsts.OPERATE_USER_TYPE_SYSTEM);

        // 操作者类型
        createOrderDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_CHANNEL);

        // 城市id
        Integer cityId = 500100;
        do {
            // 详细地址获取经纬度
            LngLatLocation areaLocation = baiduMapBService.location(orderData.getBuyerFullAddress());
            if (Objects.isNull(areaLocation)) {

                // TODO 经纬度转换
                log.info("【{}】地址信息解析失败 -【{}】", JddjConsts.CHANNEL_NAME, orderData.getBuyerFullAddress());
                break;
            }

            createOrderDTO.setLatitude(Double.valueOf(areaLocation.getLat()));
            createOrderDTO.setLongitude(Double.valueOf(areaLocation.getLng()));

            // 经纬度查找区域信息
            ResponseDTO<AreaDRO> areaResponse = areaListRemoteService.getAreaByLatAndLng(Double.valueOf(areaLocation.getLng()), Double.valueOf(areaLocation.getLat()));
            if (Objects.isNull(areaResponse) || Objects.isNull(areaResponse.getData())) {
                log.info("【{}】根据经纬度查找地址信息失败", JddjConsts.CHANNEL_NAME);
                break;
            }

            cityId = areaResponse.getData().getParentId();

            // 再设一次经纬度
            Double longitude = Double.valueOf(areaResponse.getData().getLongitude());
            Double latitude = Double.valueOf(areaResponse.getData().getLatitude());
            createOrderDTO.setLongitude(longitude);
            createOrderDTO.setLatitude(latitude);

        } while (false);

        createOrderDTO.setCityId(cityId);

        // 日志记录
        StringBuilder sbOperateLog = new StringBuilder();
        sbOperateLog.append("<br/> 订单来源类型：").append(orderData.getSrcInnerType()).
                append("<br/> 订单类型：").append(orderData.getOrderType()).
                append("<br/> 订单状态：").append(orderData.getOrderStatus()).
                append("<br/> 商家编码：").append(orderData.getOrgCode()).
                append("<br/> 买家账号：").append(orderData.getBuyerPin()).
                append("<br/> 订单来源系统：").append(orderData.getSrcOrderType());

        // 产品
        List<OrderProductDTO> orderProductList = new LinkedList<>();
        OrderProductDTO orderProductDTO = new OrderProductDTO();

        // 订单优惠
        Long discountMoney = Optional.ofNullable(orderData.getOrderDiscountMoney()).orElse(0L);
        if (CollectionUtils.isEmpty(orderData.getProduct())) {

            // 设置默认产品
            orderProductDTO.setProductShowType(GlobalConsts.NO);
            orderProductDTO.setProductId(OrderConsts.CHANNEL_DISABLED_PRODUCT_ID);
            orderProductDTO.setNumber(1);

        } else {

            if (StringUtil.isBlank(orderData.getProduct().get(0).getSkuIdIsv())) {
                orderProductDTO.setProductId(OrderConsts.CHANNEL_DISABLED_PRODUCT_ID);
                orderProductDTO.setProductShowType(GlobalConsts.NO);
            } else {
                orderProductDTO.setProductId(Integer.valueOf(orderData.getProduct().get(0).getSkuIdIsv()));
                orderProductDTO.setProductShowType(GlobalConsts.YES);
            }

            orderProductDTO.setNumber(Optional.ofNullable(orderData.getProduct().get(0).getSkuCount()).orElse(1));

            // 修改渠道预付款为用户应付金额（增加优惠）   xiewenbing 2021/04/01
            if (NumberUtil.isNotNullOrZero(orderData.getOrderBuyerPayableMoney())) {
                createOrderDTO.setChannelPrepayAmount(orderData.getOrderBuyerPayableMoney().intValue());
                createOrderDTO.setChannelPrepayStatus(PayConsts.PAY_STATUS_DONE);
            }

            // 商品优惠 2021/04/06
            Long jdPrice = Optional.ofNullable(orderData.getProduct().get(0).getSkuJdPrice()).orElse(0L);
            Long storePrice = Optional.ofNullable(orderData.getProduct().get(0).getSkuStorePrice()).orElse(0L);
            Integer count = Optional.ofNullable(orderData.getProduct().get(0).getSkuCount()).orElse(1);
            if (!Objects.equals(orderData.getProduct().get(0).getPromotionType(), JddjConsts.PRODUCT_NO_DISCOUNT_CODE)
                    && storePrice > jdPrice) {
                discountMoney += (storePrice - jdPrice) * count;
            }

            sbOperateLog.append("<br/> 到家商品编码：").append(orderData.getProduct().get(0).getSkuId()).
                    append("<br/> 到家商品名称：").append(orderData.getProduct().get(0).getSkuName()).
                    append("<br/> 商家商品编码：").append(orderData.getProduct().get(0).getSkuIdIsv());
        }

        orderProductList.add(orderProductDTO);
        createOrderDTO.setOrderProductList(orderProductList);

        // 优惠处理 xiewenbing 2021/04/01
        if (NumberUtil.isNotNullOrZero(discountMoney)) {
            List<OrderDiscountDTO> orderDiscountList = new ArrayList<>(1);
            OrderDiscountDTO orderDiscountDTO = new OrderDiscountDTO();
            orderDiscountDTO.setAmount(discountMoney.intValue());
            orderDiscountDTO.setType(OrderConsts.ORDER_DISCOUNT_TYPE_LIMIT_FREE);
            orderDiscountList.add(orderDiscountDTO);
            createOrderDTO.setOrderDiscountList(orderDiscountList);
        }

        // 设置日志记录
        sbOperateLog.append("<br/>");
        createOrderDTO.setOperatorLogRemark(sbOperateLog.toString());

        return createOrderDTO;
    }

    /**
     * 解析订单查询请求
     *
     * @param response
     * @return
     * @throws OmsBaseException
     */
    protected List<JddjOrderData> parseOrderQueryResponse(String response) throws OmsBaseException {

        // 解析数据
        JddjResponseDTO responseDTO;

        try {
            responseDTO = JSON.parseObject(response, JddjResponseDTO.class);
        } catch (Exception exception) {
            throw new OmsBaseException("解析请求应答结果异常");
        }

        if (Objects.isNull(responseDTO)) {
            throw new OmsBaseException("解析请求应答结果失败");
        }

        // 读取错误码
        int code = Integer.valueOf(responseDTO.getCode()).intValue();
        if (code != JddjConsts.RESPONSE_CODE_SUCCESS) {
            throw new OmsBaseException(Optional.ofNullable(responseDTO.getMsg()).orElse(JddjConsts.getErrorMsgByCode(code)));
        }

        if (StringUtil.isBlank(responseDTO.getData())) {
            throw new OmsBaseException("请求应答数据为空");
        }

        JddjResultDTO resultDTO;
        try {
            resultDTO = JSON.parseObject(responseDTO.getData(), JddjResultDTO.class);
        } catch (Exception exception) {
            throw new OmsBaseException("解析请求应答数据异常");
        }

        if (Objects.isNull(resultDTO)) {
            throw new OmsBaseException("解析请求应答数据失败");
        }

        code = Integer.valueOf(resultDTO.getCode()).intValue();
        if (code != JddjConsts.RESPONSE_CODE_SUCCESS) {
            throw new OmsBaseException(Optional.ofNullable(resultDTO.getMsg()).orElse(JddjConsts.getErrorMsgByCode(code)));
        }

        JddjQueryResultData queryResultData;
        try {
            queryResultData = JSON.parseObject(resultDTO.getResult(), JddjQueryResultData.class);
        } catch (Exception exception) {
            throw new OmsBaseException("解析订单查询结果数据异常");
        }

        if (Objects.isNull(queryResultData)) {
            throw new OmsBaseException("解析订单查询结果数据失败");
        }

        return queryResultData.getResultList();
    }

    /**
     * 添加创建订单任务
     *
     * @param channelOrderId
     */
    void addCreateOrderJob(String channelOrderId) {

        // 30秒后执行 创建订单
        Job job = new Job();
        job.setTaskId(TaskConsts.TASK_ID_JDDJ_ADD_CREATE_JOB + ":" + channelOrderId);
        job.setParam(TaskManager.SHARD_FIELD, TaskConsts.TASK_ID_JDDJ_ADD_CREATE_JOB);
        job.setParam("outerId", channelOrderId);
        job.setRepeatCount(1);
        Date dateRun = DateUtil.addSecond(DateUtil.getNow(), 5);
        job.setTriggerDate(dateRun);

        taskManager.submitTask2(job);
    }
}
